home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Precision Software Appli…tions Silver Collection 1
/
Precision Software Applications Silver Collection Volume One (PSM) (1993).iso
/
tutor
/
modula12.exe
/
CHAP14.TXT
< prev
next >
Wrap
Text File
|
1988-10-26
|
14KB
|
322 lines
Chapter 14 - Machine Dependent Facilities
PREREQUISITES FOR THIS MATERIAL
Before attempting to understand this material, you
should understand the material presented in Part I of this
tutorial and a clear understanding of the material on
pointers in Part II.
THIS IS WHERE YOU CAN GET INTO TROUBLE
Modula-2 does a good job of insulating you from the
underlying peculiarities of your computer due to the strong
TYPE checking which it does. It can prevent you from making
many kinds of rather stupid blunders simply by forcing you
to follow its predefined conventions. There are times,
however, when you wish to ignore some of its help and do
something that is out of the ordinary. If you had a need to
directly interface with some external device, you would need
to get down to the nitty gritty of the operating system and
do some things that are outside of the realm of normal
programming practice. Modula-2 will allow you to do such
things but you will pay a price because you take the chance
of hopelessly confusing the system.
The principles taught in this chapter can lead you
directly into the operating system where you will have more
freedom than you would have thought possible with Modula-2,
but it will place more responsibility on you. This material
is only for the advanced programmer because it will require
a knowledge of the inner workings of the computer and the
operating system. Nevertheless, it would be good for you,
as a student of Modula-2, to at least read this material,
examine the example programs, and compile and run them. You
will then have a store of knowledge of these things so that
you can use them when you need them.
TYPE RELAXATION EXAMPLE
Load and display the program named TYPEREL.MOD for an
example of a program with some very unusual type transfer
functions. Note first that three TYPES are defined, each
being the same size considering storage requirements. The
first TYPE is 10 INTEGERS, the second is 10 CARDINALS, and
the third is 20 CHAR variables which requires the same
amount of storage as 10 INTEGERS or CARDINALS. The fact
that all three TYPES are the same size is very important for
what we will do later in the program.
The first thing we do in the program part of the MODULE
is to assign a number to "Count", a CARDINAL type variable.
In the next line we assign the value of "Count" to "Index"
even though they are of different TYPES because we transform
Page 89
Chapter 14 - Machine Dependent Facilities
the TYPE in the same manner that we did back in Chapter 3
when we studied TRANSFER.MOD but this time we will go a bit
farther with the transformations. Actually, we don't need
the type transformation here because INTEGER and CARDINAL
are assignment compatible.
We load up the INTEGER array "IntVars" with some
nonsense data to work with, the data being the series of
numbers from 65 to 74, which should be easy for you to
ascertain. Then in line 23, we copy one of the array data
points to one of the other to illustrate that the type
transformation works even on array elements.
NOW FOR THE BIG TYPE TRANSFORMATION
In line 24 of the program we copy the entire field of
10 INTEGER type variables into the array of 10 CARDINAL type
variables. The only restriction is that both of the fields
must be exactly the same size which these two are. In order
to do the transformation, the TYPE of the resulting data
area is used in front of the parentheses of the source
variables. Line 25 goes a step farther and copies the new
CARDINAL data into 20 CHAR type variables, which is
permissible because 20 CHAR variables uses the same amount
of storage as 10 CARDINAL variables. You could even
transform a record made up of several different types into
all CHAR variables, or all INTEGERS, or even another
completely different record. The only requirement is that
both of the groups be exactly the same size.
This may appear to be a really neat thing to be able to
do but there are problems that you will find with this new
transformation. There are no data conversions done, only
type conversions, which means that you may wind up with a
real mess trying to decipher just what the transformed data
means. In addition, since each compiler may define the
various types of data slightly different, your program will
not be easily transportable to another computer, or maybe
not even to another compiler on the same computer.
Five of the CARDINAL numbers are displayed on the
monitor, then 10 of the CHAR numbers are displayed to show
you that they really are the same numbers. The order of the
numbers are reversed when output as individual bytes because
of the way the data is stored in the microprocessor in your
computer. This in itself is an indication that there is no
data conversion, but only a data copying, byte by byte.
One other rule must be pointed out, you cannot do a
data transformation within a function call, but it is simple
enough to do the transformation to a dummy variable and use
Page 90
Chapter 14 - Machine Dependent Facilities
the dummy variable in the function call if that is
necessary. This will be illustrated shortly. Compile and
run this program after you study it.
WORD AND ADDRESS VARIABLES
Load and display WORDADDR.MOD for an example using some
new data types. In order to get down to the lowest level of
the machine, we need these new types, ADR, WORD, and
ADDRESS, which must be IMPORTED from the pseudo module
SYSTEM. The pseudo module SYSTEM does not exist as an
external module as the others do because the kinds of things
it does are closely associated with the compiler itself.
The designers of Modula-2 have therefore defined this module
to make these things available to us.
The new data type "WORD" is compatible with all data
types that use a single word for storage, but it is somewhat
limited in what you can do with it. It is most useful as the
formal argument to a function which can be called with any
data type that is contained in one word. In lines 27 and
28, the same procedure is called, once with an INTEGER, and
once with a CARDINAL. Since the procedure is designed to
handle either, it will print out both numbers by converting
them first to CARDINAL using the type transformation in line
17, then calling the output procedures. Once again, the
type transformation cannot be done in the procedure call so
a temporary variable is used.
A NEW KIND OF POINTER
The variable "Peach" is assigned the type ADDRESS which
is also imported from the pseudo module SYSTEM, and is
therefore a pointer to any WORD type of variable. Peach can
therefore point to an INTEGER or a CARDINAL as is done in
lines 25 and 26. The procedure "ADR" returns the address of
any WORD type of variable and it too must be IMPORTED from
the pseudo module SYSTEM.
ABSOLUTE ADDRESSES
Notice the two strange looking variables in lines 10
and 11. The variable "MonoVideo" is an array of 4000 CHAR
type variables but we have forced it to be located at a very
specific location in memory, namely at segment=B000(hex) and
offset=0000(hex). This is the method provided for you by
Modula-2 by which you can force a variable to be at a
specific memory location. In this case we have defined the
variable to be stored in the locations in memory where the
monochrome monitor display is stored so we can store data
directly into the monochrome monitor display area.
Page 91
Chapter 14 - Machine Dependent Facilities
The variable "ColorVideo" is the same except that the
location referenced is that area where the output for a
color monitor is stored. You can see that you can gain
control over the actual hardware with this capability but it
does require a lot of knowledge of the hardware and the
operating system.
In the last line of the program the variable "Peach" is
assigned the address of a specific location as an
illustration only. This is only possible because "Peach" is
a variable of type ADDRESS.
It should be clear to you that with these functions, it
is possible to do a lot of data shuffling that could not
otherwise be done. The next example program will illustrate
their use further.
MORE ADDRESSING EXAMPLES
Load and display the program ADRSTUFF.MOD. This
program uses the ADDRESS type and adds two new, rather
simple functions, SIZE and TSIZE. Actually, these are not
completly new since we used the TSIZE function in the
chapter on pointers and dynamic allocation. These two
functions will return the size in bytes of any variable or
of any type. The program on your monitor has several types
defined, then several variables, and finally initializes all
of the elements of the array "Stuff" to some nonsense data.
The really interesting things begin happening at line 25.
The pointer "NeatPoint" is pointed at the first element
of the array "Stuff", and its value is dereferenced into
"Index". The type transformation is required because the
result of the dereferencing is a CARDINAL. The data is
written out. Next the size of the type "IntArray" is
assigned to the variable "IncreAmt", which should be 8 words
or 16 bytes. In line 29 we do some pointer arithmetic by
adding the size of the type "IntArray" to the original value
of the pointer which should cause it to point to the next
row of the array. After dereferencing the pointer and
getting its new value, we print it out to find that it did
indeed move to the next row of the array.
Based on the above discussion, it should be apparent to
you that you can move the pointer all around the array named
"Stuff" and get whatever data you wish. The next section
uses a loop to continue the process through all five rows.
The only thing that may be confusing is line number 34 where
we get the size of the "BigArray" type and divide it by the
size of the "IntArray" type. The result should be 5, and
Page 92
Chapter 14 - Machine Dependent Facilities
you will see that it does five iterations through the loop.
This is really a dumb way to get through this particular
loop but it is only for purposes of illustration that it is
done. Notice all of the type transformations to INTEGER in
these statements, this is because the functions all return a
CARDINAL type of data. Doing all of this in CARDINAL
numbers would have made it much cleaner, but this was more
illustrative for you.
TWO MORE LINES OF ILLUSTRATION
Lines 42 and 43 are given as an illustration for you of
how to use the SIZE function. It simply returns the size in
bytes, of any variable used as an argument.
PROGRAMMING EXERCISES
1. Modify the "AdrStuff" module to print out some of the
type and variable sizes such as those calculated in
lines 41 and 42.
2. Write a program with an array of 100 CARDINAL elements,
fill the elements with nonsense data, and use a pointer
to print out every 12th value starting at the highest
element (number 100) and working downward.
Page 93